import { IFileOption, IIconfontSvgs, ISvgOptions } from "./types";

const fs = require("fs");
const path = require("path");

export function checkAndMakeDirPath(dirPath: string): void {
  // if (fs.existsSync(dirPath) && fs.statSync(dirPath).isDirectory()) return;
  if (fs.existsSync(dirPath)) return;
  const preDir = path.parse(dirPath).dir;
  if (!fs.existsSync(preDir) || !fs.statSync(preDir).isDirectory()) {
    checkAndMakeDirPath(preDir);
  }
  fs.mkdirSync(dirPath);
}

export function getContentFromSvg(content: string, level: number = 0): string {
  const svgtMatch = content.match(/<svg+.*?>\s*([\s\S]*?)\s*<\/svg*?>/) || [];
  return svgtMatch[level] || "";
}

// 获取并解析Symbols列表
export function getIconfontContent(inputPath: string): IIconfontSvgs {
  const content = fs.readFileSync(inputPath, "utf-8").toString();
  const svgContnt = getContentFromSvg(content, 1);
  const svgId = (svgContnt.match(/<svg.+id="(.*?)".*?>/) || [])[1] || "";
  const svgList = svgContnt
    .split("</symbol>")
    .filter(Boolean)
    .map((item) => {
      const name = (item.match(/<symbol.+id="(.*?)"/) || [])[1];
      const viewBox = (item.match(/<symbol.+viewBox="(.*?)"/) || [])[1];
      const content = item.replace(/<symbol.+?>/, "");
      return {
        name,
        viewBox,
        content,
      };
    });
  return {
    svgId,
    svgList,
  };
}

// 读取svg文件
export function readSvgFiles(
  filePath: string,
  options?: IFileOption
): ISvgOptions[] {
  let svgList: ISvgOptions[] = [];
  const { isPure, isDeep } = options || {};
  if (fs.existsSync(filePath)) {
    if (fs.statSync(filePath).isDirectory()) {
      // 目录
      const fileList = fs.readdirSync(filePath);
      const dirName = path.parse(filePath).base;
      const nOptions = { ...options };
      if (dirName === "pure") {
        nOptions.isPure = true;
      }
      if (Array.isArray(fileList) && fileList.length) {
        fileList.forEach((fileName) => {
          const childPath = path.join(filePath, fileName);
          // 如果isDeep配置为false则不继续深入下一层目录中
          if (fs.statSync(childPath).isDirectory() && !isDeep) return;
          const svgs = readSvgFiles(childPath, nOptions);
          svgList = [...svgList, ...svgs];
        });
      }
    } else if (/\.svg$/.test(filePath)) {
      const fileId = path.parse(filePath).base?.replace(/\.svg$/, "");
      // svg文件
      const fileText: string = fs
        .readFileSync(filePath)
        .toString()
        .replace(/(\r|\n)/g, " ");
      let svgText = getContentFromSvg(fileText)
        // remove title tag
        .replace(/<title+.*?>\s*([\s\S]*?)\s*<\/title*?>/, "")
        // remove desc tag
        .replace(/<desc+.*?>\s*([\s\S]*?)\s*<\/desc*?>/, "")
        // remove commom
        .replace(/<!--+.*?-->/, "")
        // remove tag id
        .replace(/id=("|')+.*?("|')/g, "")
        // reduce space num
        .replace(/\s+/g, " ");
      const viewBox = (svgText.match(/viewBox=("|')([\d\s]+)("|')/) || [])[2];
      svgText = svgText.replace(/<svg+.*?>/, "").replace(/\s*<\/svg*?>/, "");
      if (isPure) {
        const fillNone = "@#xxxx#@";
        svgText = svgText
          .replace(/fill=("|')none?("|')/g, fillNone)
          .replace(/fill=("|')+.*?("|')/g, 'fill="currentColor"')
          .replace(new RegExp(fillNone, "g"), 'fill="none"');
      }
      svgList.push({
        name: fileId,
        content: svgText,
        viewBox,
      });
    }
  }
  return svgList;
}

export function getOutputPath(
  outputValue: string | undefined,
  defaultFileName: string,
  ext: string
) {
  const outputPathList: string[] = (outputValue || "")
    .split("/")
    .filter(Boolean);
  let outputPath = path.join(process.cwd(), ...outputPathList);
  const outputParse = path.parse(outputPath);
  if (
    fs.existsSync(outputPath) &&
    (outputParse.ext !== ext || fs.statSync(outputPath).isDirectory())
  ) {
    checkAndMakeDirPath(outputPath);
    outputPath = path.join(outputPath, defaultFileName);
  } else if (!fs.existsSync(outputPath)) {
    if (outputParse.ext === ext) {
      checkAndMakeDirPath(outputParse.dir);
    } else {
      checkAndMakeDirPath(outputPath);
      outputPath = path.join(outputPath, defaultFileName);
    }
  }
  return outputPath;
}
